package com.tanhua.dubbo.server.api;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.dubbo.server.service.IdService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service(version = "1.0.0")
public class QuanZiApiImpl implements QuanZiApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    //发布动态
    @Override
    public String savePublish(Publish publish) {
        //校验信息是否有效
        if (publish.getUserId() == null)
            return null;
        try {
            //先存储在发布表
            publish.setId(ObjectId.get());
            publish.setCreated(System.currentTimeMillis());
            publish.setPid(idService.createId("publish", publish.getId().toHexString()));
            mongoTemplate.save(publish);
            //存储相册表
            Album album = new Album();
            album.setId(ObjectId.get());
            album.setPublishId(publish.getId());
            album.setCreated(System.currentTimeMillis());
            //每个用户单独使用一张相册表
            mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());

            //存储在朋友的时间线表
            //查询好友id
            Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
            List<Users> users = mongoTemplate.find(query, Users.class);
            for (Users user : users) {
                TimeLine timeline = new TimeLine();
                timeline.setId(ObjectId.get());
                timeline.setDate(System.currentTimeMillis());
                timeline.setPublishId(publish.getId());
                timeline.setUserId(publish.getUserId());
                mongoTemplate.save(timeline, "quanzi_time_line_" + user.getFriendId());
            }
            return publish.getId().toHexString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {
        //查时间线表,获得发布id
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
        Query query = new Query();
        query.with(pageRequest);
        List<TimeLine> timeLines = null;
        if (userId == null) {
            timeLines = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_recommend");
        } else {
            timeLines = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        }
        Set<ObjectId> publishIds = timeLines.stream().map(TimeLine::getPublishId).collect(Collectors.toSet());

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);
        return publishList;
    }

    //查询单条动态信息
    @Override
    public Publish queryPublishById(String publishId) {
        Query query = Query.query(Criteria.where("id").is(publishId));
        return mongoTemplate.findById(new ObjectId(publishId), Publish.class);
    }

    /**
     * 点赞
     *
     * @param userId
     * @param publishId
     */
    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        //如果同一个用户对一条动态点过赞了,则直接返回false
        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId)).and("userId").is(userId).and("commentType").is(1));
        long count = mongoTemplate.count(query, Comment.class);
        if (count > 0)
            return false;
        return saveComment(userId, publishId, 1, null);
    }

    //取消点赞,喜欢等
    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {
        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId)).and("userId").is(userId).and("commentType").is(commentType));
        DeleteResult result = mongoTemplate.remove(query, Comment.class);
        return result.getDeletedCount() > 0;
    }

    //喜欢
    @Override
    public boolean saveLoveComment(Long userId, String publishId) {
        //如果同一个用户对一条动态点过喜欢了,则直接返回false
        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId)).and("userId").is(userId).and("commentType").is(3));
        long count = mongoTemplate.count(query, Comment.class);
        if (count > 0)
            return false;
        return saveComment(userId, publishId, 3, null);
    }

    /**
     * 保存评论
     *
     * @param userId
     * @param publishId
     * @param type
     * @return
     */
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {
        try {
            Comment comment = new Comment();
            comment.setId(ObjectId.get());
            comment.setUserId(userId);
            comment.setContent(content);
            comment.setPublishId(new ObjectId(publishId));
            comment.setCommentType(type);
            comment.setCreated(System.currentTimeMillis());
            /*
            * 存储发布人信息publishUserId
            此处publishId三种可能:
            *   动态id
            *   小视频id
            *   评论id
            * */
            Publish publish = mongoTemplate.findById(comment.getPublishId(), Publish.class);
            if (null != publish) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                Video video = mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (null != video) {
                    comment.setPublishUserId(video.getUserId());
                } else {
                    Comment rComment = mongoTemplate.findById(comment.getPublishId(), Comment.class);
                    comment.setPublishUserId(rComment.getUserId());
                }
            }
            this.mongoTemplate.save(comment);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    //查看评论数
    @Override
    public Long queryCommentCount(String publishId, Integer type) {
        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId)).and("commentType").is(type));
        return mongoTemplate.count(query, Comment.class);
    }

    /**
     * 查询评论
     *
     * @return
     */
    @Override
    public List<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {
        //按评论时间升序排列
        Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc("created")));
        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId)).and("commentType").is(2)).with(pageable);
        return mongoTemplate.find(query, Comment.class);
    }

    /**
     * 查询其他用户对本用户的点赞,评论,喜欢列表
     *
     * @return
     */
    @Override
    public List<Comment> queryCommentListByUser(Long userId, Integer type, Integer page, Integer pageSize) {
        Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc("created")));
        Query query = Query.query(Criteria.where("publishUserId")
                .is(userId).and("commentType").is(type)).with(pageable);
        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);
        return commentList;
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pids) {
        Query query = Query.query(Criteria.where("pid").in(pids));
        return mongoTemplate.find(query, Publish.class);
    }

    @Override
    public List<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {
        Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageable);
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        if (CollectionUtils.isEmpty(albumList))
            return null;
        Set<ObjectId> publishIds = albumList.stream().map(Album::getPublishId).collect(Collectors.toSet());
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = mongoTemplate.find(queryPublish, Publish.class);
        return publishList;
    }
}
